﻿namespace demo.Web.Services
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Data;
    using System.Linq;
    using System.ServiceModel.DomainServices.EntityFramework;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using demo.Web;
    using demo.Web.PresentationModel;


    // Implements application logic using the azureriademoEntities context.
    // TODO: Add your application logic to these methods or in additional methods.
    // TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
    // Also consider adding roles to restrict access as appropriate.
    // [RequiresAuthentication]
    [EnableClientAccess()]
    public class DeptDomainService : LinqToEntitiesDomainService<azureriademoEntities>
    {


        Action<PMDepartment, department> MapDeptIDAction;
        Action<PMEmployee, employee> MapEmpIDAction;


        public DeptDomainService()
        {
            MapDeptIDAction = MapDeptID;
            MapEmpIDAction = MapEmpID;
        }



        #region department get/add/update

   
        public IQueryable<PMDepartment> GetDepartmentsPM()
        {
            var qry = this.ObjectContext.departments
                        .OrderBy(d => d.ID)
                        .Select(d => new PMDepartment()
                        {
                            ID = d.ID,
                            Name = d.Name,
                            employees = d.employees.SelectMany<employee, PMEmployee>
                                        (de => this.ObjectContext.employees
                                            .Where(ee => ee.DeptID == d.ID)
                                            .Select(e => new PMEmployee()
                                            {
                                                ID = e.ID,
                                                Name = e.Name,
                                                Addr = e.Addr,
                                                Ext = e.Ext,
                                                DeptID = (int)e.DeptID
                                            })
                                        )
                        });

            return qry;

        }


        public void InsertPMDepartment(PMDepartment pmDepartment)
        {
            department dbDept = new department();

            // on insert, we only care about dept. Name.  ID will be assigned
            dbDept.Name = pmDepartment.Name;

            this.ObjectContext.departments.AddObject(dbDept);

            // associate this PM object with DB object so we can pass back the unique ID set by database
            this.ChangeSet.Associate(pmDepartment, dbDept, MapDeptIDAction);
        }


        private void MapDeptID(PMDepartment pmDept, department dbDept)
        {
            pmDept.ID = dbDept.ID;
        }


        public void UpdatePMDepartment(PMDepartment currenPMDepartment)
        {
            PMDepartment origDept = this.ChangeSet.GetOriginal(currenPMDepartment);

            department dbDept = this.ObjectContext.departments.Where(d => d.ID == currenPMDepartment.ID).FirstOrDefault();

            // pick up any changes
            if (dbDept.Name != currenPMDepartment.Name)
                dbDept.Name = currenPMDepartment.Name;

        }

        #endregion


        #region Employee get/get by dept/add

        public IQueryable<PMEmployee> GetPMEmployees()
        {
            var qry = this.ObjectContext.employees
                .OrderBy(d => d.DeptID)
                .ThenBy(d => d.ID)
                .Select(d => new PMEmployee()
                {
                    ID = d.ID,
                    Name = d.Name,
                    Addr = d.Addr,
                    Ext = d.Ext
                });

            return qry;
        }

        public IQueryable<PMEmployee> GetPMEmployeesForDept(int DeptID)
        {
            var qry = this.ObjectContext.employees
                .Where(d => d.DeptID == DeptID)
               .OrderBy(d => d.DeptID)
               .ThenBy(d => d.Name)
               .Select(d => new PMEmployee()
               {
                   ID = d.ID,
                   Name = d.Name,
                   Addr = d.Addr,
                   Ext = d.Ext,
                   DeptID = DeptID,
               });

            return qry;
        }

        public void InsertPMEmployee(PMEmployee employee)
        {
            employee dbEmployee = new employee();

            // on insert, we only care about dept. Name.  ID will be assigned
            dbEmployee.Name = employee.Name;
            dbEmployee.Addr = employee.Addr;
            dbEmployee.Ext = employee.Ext;
            dbEmployee.DeptID = employee.DeptID;

            this.ObjectContext.employees.AddObject(dbEmployee);

            // associate this PM object with DB object so we can pass back the unique ID set by database
            this.ChangeSet.Associate(employee, dbEmployee, MapEmpIDAction);


        }


        private void MapEmpID(PMEmployee pmEmp, employee dbEmp)
        {
            pmEmp.ID = dbEmp.ID;
        }


        #endregion


    }
}


